STV2022 – Store tekstdata

[02] Anskaffelse og innlasting av tekst


Martin Søyland <>

Disposisjon

  1. Strukturerte datasett
  2. Semistrukturerte data (APIer)
  3. Ustrukturerte data
    • Skraping (med eksempler)
    • Kravling (med eksempler)
    • Fallgruver
  4. Kaosdata (Høyland & Søyland)
    • En historie om OCR
  5. Oppsummering
  6. Oppgave

Strukturerte datasett

European Values Study
Varieties of Democracy
Stortingscrape

Fivethithyeight
Parlgov
Quality of Government

Strukturerte datasett

  • Datasett som er klar out of the box
  • oftest 2-dimensjonale: data[rader, kolonner]
  • … men mange trenger fortsatt preprosessering
tibble(stortingscrape::cases$root) %>%      # Henter ut data fra stortingscrape
  select(id, status, type, title_short) %>% # Trekker ut relevante variabler
  slice_sample(n = 5)                       # Viser 5 tilfeldige enheter
## # A tibble: 5 × 4
##   id    status         type          title_short                                
##   <chr> <chr>          <chr>         <chr>                                      
## 1 80332 til_behandling alminneligsak Grunnlovsforslag om ny § 107 (rett til bol…
## 2 79518 behandlet      alminneligsak Redegjørelse av utenriksministeren om vikt…
## 3 79329 behandlet      budsjett      Innstilling fra finanskomiteen om Endringe…
## 4 79932 behandlet      alminneligsak Representantforslag om å sørge for at alle…
## 5 77424 behandlet      budsjett      Endringar i statsbudsjettet 2019 under Olj…

Vanlige dataformat

Format Står for R-funksjon
.csv Comma Separated Values read.csv // readr::read_csv()
.txt Text readLines() // textreadr::read_document()
.xlsx Excel readxl::read_xlsx()
.html HyperText Markup Language rvest::read:html()
.xml Extensible Markup Language rvest::read:html()
.json JavaScript Object Notation jsonlite::read_json()
.dta Stata haven::read_dta()
.sav SPSS haven::read_sav()
Og tusen andre formater… …med egne R-pakker og funksjoner

Semistrukturerte data (APIer)

Application Programming Interface:

API

Mer i forelesning

[05] Bruke API (Stortinget) (uke 38)

Tilfeldig side fra Statens vegvesen



## <?xml version="1.0" encoding="utf8"?>
## <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:skos="http://www.w3.org/2004/02/skos/core#">
##   <rdf:Description rdf:about="https://psi.norge.no/los/ord/parkering-og-hvileplasser">
##     <rdf:type rdf:resource="http://www.w3.org/2004/02/skos/core#Concept"/>
##     <skos:inScheme rdf:resource="https://psi.norge.no/los/ontologi/ord"/>
##     <skos:prefLabel xml:lang="nn">Parkering</skos:prefLabel>
##     <skos:prefLabel xml:lang="nb">Parkering og hvileplasser</skos:prefLabel>
##     <skos:prefLabel xml:lang="en">Parking and rest area</skos:prefLabel>
##     <skos:hiddenLabel xml:lang="nb">Avgiftsparkering</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nn">Avgiftsparkering</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nb">Innfartsparkering</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nn">Innfartsparkering</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nb">Parkeringsavgift</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nn">Parkeringsavgift</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nb">Parkeringsbot</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nn">Parkeringsbot</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nb">Parkeringsgebyr</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nn">Parkeringsgebyr</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nb">Parkeringskort</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nn">Parkeringskort</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nn">Parkeringsløyve</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nb">Parkeringsløyve</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nn">Parkeringsløyve</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nb">Parkeringsplass</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nn">Parkeringsplass</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nb">Parkeringstillatelse</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nn">Rasteplassar</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nb">Rasteplasser</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nb">Utfartsparkering</skos:hiddenLabel>
##     <skos:hiddenLabel xml:lang="nn">Utfartsparkering</skos:hiddenLabel>
##     <skos:note xml:lang="nn">Det skal vere eitt felles regelverk for all parkeringsverksemd. Regelverket skal syte for lik skilting og like reaksjonar ved brot på føresegnene. Det er også ei obligatorisk godkjenningsordning som gjeld både for kommunar, private parkeringsselskap og andre.</skos:note>
##     <skos:note xml:lang="nb">Parkeringstillatelser, parkeringsgebyr, regelverk for gateparkering, parkering for forflytningshemmede, klage på parkeringsbot, betaling av parkeringsbot.</skos:note>
##     <skos:broader rdf:resource="https://psi.norge.no/los/tema/mobilitetstilbud"/>
##     <skos:broader rdf:resource="https://psi.norge.no/los/tema/veg-og-vegregulering"/>
##     <skos:broader rdf:resource="https://psi.norge.no/los/tema/yrkestransport"/>
##   </rdf:Description>
## </rdf:RDF>

Ustrukturerte data



Skraping vs. kravling

Skraping

Skraping

  • Eksempelhypotese:

Skandinaviske land blir nevnt oftere enn andre land i NOUer fra Utenriksdepartementet

  1. Utvalg/univers: aller NOUer fra UD
  2. Datakilde: regjeringen.no
  3. Fremgangsmåte 1: Laste ned alle 7 dokumentene manuelt
  4. Fremgangsmåte 2: Lage en scraper som laster ned og strukturerer dokumentene

Steg 1: Finne data

library(rvest)
library(stringr)

# rot-url for regjeringen.no
base_url <- "https://www.regjeringen.no"

# Laster ned siden med alle NOUer fra UD (atm 7 stk)
## str_c(base_url, "no/dokument/nou-ar/id1767/?ownerid=833") %>% 
##   download.file(., destfile = "./scrape/base.html")
## 
# Trekker ut linkene til hver NOU
nou_links <- read_html("./scrape/base.html") %>% 
  html_elements("li > h2 > a[data-hitid]") %>% 
  html_attr("href")

paste0(base_url, nou_links)
## [1] "https://www.regjeringen.no/no/dokumenter/nou-2016-8/id2503028/"
## [2] "https://www.regjeringen.no/no/dokumenter/nou-2012-2/id669368/" 
## [3] "https://www.regjeringen.no/no/dokumenter/nou-2009-19/id571718/"
## [4] "https://www.regjeringen.no/no/dokumenter/nou-2008-14/id525832/"
## [5] "https://www.regjeringen.no/no/dokumenter/nou-2003-32/id149022/"
## [6] "https://www.regjeringen.no/no/dokumenter/nou-1995-5/id139818/" 
## [7] "https://www.regjeringen.no/no/dokumenter/nou-1994-9/id139452/"

Steg 2: Laste ned forside for alle NOUer

# Laster ned forsiden til hver NOU
for(i in nou_links){
  
  # Trekker ut dokument-id
  tmp_id <- str_extract(i, "id[0-9]+")
  
  # Laster ned forsiden til NOU i
  str_c(base_url, i) %>% 
    download.file(., destfile = str_c( "./scrape/nou_forside/", 
                                       tmp_id, 
                                       ".html"))
  
  # Legger til litt tilfeldig søvn
  Sys.sleep(2 + abs(rnorm(1, 0)))
  
  # Printer en beskjed til console om at i nå er ferdig
  message(str_c(
    "Ferdig med: ",
    tmp_id,
    "\n"
  ))
  
}
# Lister opp forsidene vi har lagret
list.files("./scrape/nou_forside/")
## [1] "id139452.html"  "id139818.html"  "id149022.html"  "id2503028.html"
## [5] "id525832.html"  "id571718.html"  "id669368.html"
# Les inn hver forsidefil med read_html()
nou_forsider <- lapply(
  list.files("./scrape/nou_forside/", full.names = TRUE), 
  read_html
)

# Viser første listeelement
nou_forsider[[1]]
## {html_document}
## <html class="no-js" lang="no">
## [1] <head>\n<meta http-equiv="Content-Type" content="text/html; charset=UTF-8 ...
## [2] <body class="page-horing ">\r\n\r\n<!-- There is a copy of this in /Error ...

Steg 3: Laste ned .pdf for alle NOUene

  • Se på forsiden til én NOU og identifiser nedlastingsknappen
  • Inspect -> Copy selector -> Rediger og test
  • Skriv kode for å trekke ut lenkene
  • Last ned .pdf-filene
# Prosesserer hvert listeelement
nou_pdf_links <- sapply(nou_forsider, function(x){
  
  tmp_content_link <- x %>%       # Trekk ut listeelement x
    html_elements("a[title]") %>% # Trekk ut html nodene "a" som har egenskapen "title"
    html_attr("href")             # Trekk ut teksten til egenskapen "href"
  
  # Trekk ut bare de linkene som inneholder ".pdf" på slutten av strengen
  tmp_content_link %>% 
    magrittr::extract(str_detect(., "\\.pdf$"))
  
  
})

# Vis linkene
nou_pdf_links
## [1] "/contentassets/bee23e85425c4fca84346e100bf745c7/no/pdfa/nou199419940009000dddpdfa.pdf"
## [2] "/contentassets/3a80ddef404745e5be000a9f58a762a1/no/pdfa/nou199519950005000dddpdfa.pdf"
## [3] "/contentassets/28ed358f13704ed2bb3c2a7f13a02be9/no/pdfs/nou200320030032000dddpdfs.pdf"
## [4] "/contentassets/09faceca099c4b8bac85ca8495e12d2d/no/pdfs/nou201620160008000dddpdfs.pdf"
## [5] "/contentassets/9b801d1fe4804a9a9e30d8d621a3b021/no/pdfs/nou200820080014000dddpdfs.pdf"
## [6] "/contentassets/0a903cdd09fc423ab21f43c3504f466a/no/pdfs/nou200920090019000dddpdfs.pdf"
## [7] "/contentassets/5d3982d042a2472eb1b20639cd8b2341/no/pdfs/nou201220120002000dddpdfs.pdf"
# Laster ned pdf til hver NOU
for(i in nou_pdf_links){
  
  # Trekker ut dokument-id
  tmp_id <- str_extract(i, "nou(.*?)\\.pdf$")
  
  # Laster ned forsiden til NOU i
  str_c(base_url, i) %>% 
    download.file(., destfile = str_c("./scrape/nou_pdf/", 
                                      tmp_id))
  # Legger til litt tilfeldig søvn
  Sys.sleep(2 + abs(rnorm(1, 0)))
  
  # Printer en beskjed til console om at i nå er ferdig
  message(str_c(
    "Ferdig med: ",
    tmp_id,
    "\n"
  ))
  
}

# Lister opp filene
list.files("./scrape/nou_pdf/")
## [1] "nou199419940009000dddpdfa.pdf" "nou199519950005000dddpdfa.pdf"
## [3] "nou200320030032000dddpdfs.pdf" "nou200820080014000dddpdfs.pdf"
## [5] "nou200920090019000dddpdfs.pdf" "nou201220120002000dddpdfs.pdf"
## [7] "nou201620160008000dddpdfs.pdf"

Steg 4: Laste inn .pdf-filene

  • Her bruker vi textreadr::read_pdf()
library(textreadr)

# Lager objekt for filbane til alle pdfene
nou_pdfer <-  list.files("./scrape/nou_pdf/", full.names = TRUE)

# Gå gjennom hver fil og...
nou_tekst <- lapply(nou_pdfer, function(x){
  
  # ... les pdfen og gjør det om til en tibble
  read_pdf(x) %>% tibble()
  
})

# Viser de første 4 radene på listeelement 1
nou_tekst[[1]] %>% 
  head(., 4)
## # A tibble: 4 × 3
##   page_id element_id text                                                       
##     <int>      <int> <chr>                                                      
## 1       1          1 "NORGES OFFENTLIGE UTREDNINGER\n                    NOU 19…
## 2       2          1 "Til Utenriksdepartementet\nHurtigbåtutvalget som ble oppn…
## 3       3          1 "NOU 1994:9\nKapittel 1         Om sikkerhet og forhold so…
## 4       4          1 "NOU 1994:9\nKapittel 1       Om sikkerhet og forhold som …

Steg 5: Konvertere til .txt

# Fra 1 til 7 (antall NOUer) ...
lapply(1:length(nou_tekst), function(x){
  
  tmp_tekst <- nou_tekst[[x]] %>%            # ...trekk ut listeelement x (1:7)
    summarize(tekst = str_c(text,            # ...og slå sammen teksten til én tekstbolk
                            collapse = " "))
  
  
  txt_file_out <- nou_pdfer[x] %>%           # Trekk ut filbane for x
    str_extract("nou[0-9]+(.*?)\\.pdf") %>%  # Trekk ut bare filnavn for filbanen til x
    str_remove("\\.pdf")                     # Fjern ".pdf" fra filbanen til x
  
  
  writeLines(tmp_tekst$tekst,            # Skriv teksten til en .txt fil
             str_c("./scrape/nou_txt/",  # som skal lagres i mappen ./scrape/nou_txt/
                   txt_file_out,         # med navnet vi laget over
                   ".txt"))              # og .txt suffix
  
})

Steg 6: Neste forelesning …

… men husk hypotesen:

Skandinaviske land blir nevnt oftere enn andre land i NOUer fra Utenriksdepartementet

OBS!

Dependent variable:
n
Skand. land 168.631***
(52.106)
Konstantledd 34.569***
(8.884)
Observations 172
Adjusted R2 0.052
Note: p<0.1; p<0.05; p<0.01

Kravling

Edderkopp

  • La oss kravle litt rundt på Virksomme ord
  • Dette vil ta lang tid! Husk å teste først
  • Se på “Taler – kronologisk”
  • Gå inn på en tale og legg merke til linken /tale/xxxx/
  • Setter kravleren til å bare lagre disse

Ca. 4 timer kjøretid

# Laster inn pakke for kravling
library(Rcrawler)


Rcrawler("http://virksommeord.no/", # Nettsiden vi skal kravle
         DIR = "./crawl",           # mappen vi lagrer filene i
         no_cores = 4,              # kjerner for å prosessere data
         dataUrlfilter = "/tale/",  # subset filter for kravling
         RequestsDelay = 2 + abs(rnorm(1)))
# Lager en vektor med alle filnavn
virkord_filer <- list.files("./crawl/virksommeord.no-101413", 
                            full.names = TRUE)

# Viser de første filene i vektoren...
head(virkord_filer)
## [1] "./crawl/virksommeord.no-101413/1 .html"   
## [2] "./crawl/virksommeord.no-101413/10 .html"  
## [3] "./crawl/virksommeord.no-101413/100 .html" 
## [4] "./crawl/virksommeord.no-101413/1000 .html"
## [5] "./crawl/virksommeord.no-101413/1001 .html"
## [6] "./crawl/virksommeord.no-101413/1002 .html"
# Og lengden på vektoren
length(virkord_filer)
## [1] 5100

Kravlingens etterarbeid

# Leser inn alle filene fra kravlingen
virkord_html <- lapply(virkord_filer, rvest::read_html)

# Går gjennom alle filene med preprosessering
virkord_data <- lapply(1:length(virkord_html), function(x){
  
  tmp_tekst <- virkord_html[[x]] %>%               
    html_elements("div[class='document'] > p") %>% # Trekker ut elementene <div class="document"> etterfulgt av <p>
    html_text()                                    # Konverterer til tekst
  
  if(identical(character(), tmp_tekst)){           # Hvis teksten er tom...
    tmp_tekst <- virkord_html[[x]] %>%             #
      html_elements("tr[valign='top']") %>%        # ...trekker jeg ut <tr valign="top>
      html_text()                                  # og gjør om til tekst
  }
  
  if(identical(character(), tmp_tekst)){              # Hvis teksten fortsatt er tom...
    tmp_tekst <- virkord_html[[x]] %>%                #
      html_elements("div[class='document'] > h3") %>% # ...trekker jeg ut elementene <div class="document"> etterfulgt av <h3>
      html_text() %>%                                 # ...gjør om til tekst
      str_split(., "\\n") %>%                         # ...splitter opp i linjer
      unlist()                                        # ... og konverterer fra liste til vektor
  }
  
  # Trekker ut forfatternavn
  tmp_forfatter <- virkord_html[[x]] %>% 
    html_elements("div[class='tale-header'] > ul[class='byline'] > li > a") %>% 
    html_text() %>% 
    str_replace_all(., "\\s+", " ") %>% 
    .[1]
  
  # Trekker ut link til forfatterside
  tmp_forfatter_link <- virkord_html[[x]] %>% 
    html_elements("div[class='tale-header'] > ul[class='byline'] > li > a") %>% 
    html_attr("href") %>% 
    .[which(str_detect(., "person"))]
  
  # Trekker ut tittel
  tmp_tittel <- virkord_html[[x]] %>% 
    html_elements("div[class='tale-header'] > h1") %>% 
    html_text() %>% 
    str_replace_all(., "\\s+", " ")
  
  # Setter alt sammen til en tibble
  tmp_data <- tibble(
    tittel = tmp_tittel,
    forfatter = tmp_forfatter,
    forfatter_link = tmp_forfatter_link,
    avsnitt = 1:length(tmp_tekst),
    tekst = tmp_tekst
  )
  
  return(tmp_data)
})

# Binder så sammen alle tibbles i listen "virkord_data"
# Til å være én tibble
virkord <- bind_rows(virkord_data)


# save(virkord, file = "./crawl/virksommeord.rda")
# Viser de 6 øverste radene i datasettet
virkord %>% sample_n(6)
## # A tibble: 6 × 5
##   tittel                                           forfa…¹ forfa…² avsnitt tekst
##   <chr>                                            <chr>   <chr>     <int> <chr>
## 1 "200 år som sentralbank i en liten, åpen økonom… Øystei… /perso…      72 "Fry…
## 2 "Vårt innsatsforsvar - i en relevant Allianse"   Anne-G… /perso…     178 "Vi …
## 3 "Økonomiske perspektiver"                        Øystei… /perso…      66 "Jeg…
## 4 "«Å skape brorskap» "                            Grete … /perso…       8 "Alt…
## 5 "Folkefrihed og Folkeforening"                   Marcus… /perso…      22 "Man…
## 6 "Vilje til endringer og nye løsninger"           Harald… /perso…      83 "Reg…
## # … with abbreviated variable names ¹​forfatter, ²​forfatter_link

Fallgruver



Fallguys

Front-end vs. back-end

  • Regjeringensarkiv
    • regjeringen.no har ikke åpen API
    • men har en back-end API som henter data for oss som gjør siden lesbar
  • Se på Network i Inspect
    • data henter .json-fil back-end
    • merk: "Page":1, "Hits":20, "TotalHits":71, osv

Overlaste serveren (timeout)

Lagring

  • Alltid lagre lokalt!
    • slipper å hente samme side flere ganger
    • reproduserbarhet -> nettsider endrer seg
    • download.file() er din venn

robots.txt

  • robots.txt eksisterer på de fleste nettsider
    • beskriver hva som er lov og ikke lov å skrape
##  [1] "User-agent: *"                                              
##  [2] "Disallow: /tegneserier/salesposter"                         
##  [3] "Disallow: /poll"                                            
##  [4] ""                                                           
##  [5] "user-agent: Googlebot-News"                                 
##  [6] "disallow: /annonsorinnhold/"                                
##  [7] "disallow: /kommersielt-innhold/"                            
##  [8] "disallow: /innstikk/"                                       
##  [9] "disallow: /?embed=true"                                     
## [10] "disallow: /arkiv/"                                          
## [11] "disallow: /front/"                                          
## [12] "disallow: /ads/prewarm/"                                    
## [13] "disallow: /adblock-survey/"                                 
## [14] ""                                                           
## [15] "Sitemap: https://www.vg.no/sitemap/files/articles-48hrs.xml"
## [16] "Sitemap: https://www.vg.no/sitemap/sitemap.xml"

Kaosdata: En historie om OCR

Høyland & Søyland (2019):

  • Hypotese:
    • Mer partisentererte valgsystemer gir mer “partisnakk”
  • Data:
    • Stortingstaler fra 1910-1931
  • Fremgangsmåte:
    • Kvantitativ emneanalyse på tvers av den norske valgreformen i 1919
  • Funn:
    • Ja, valgreform endrer atferd
  • Implikasjon:
    • Valgsystemet endrer representanters vekting av å følge partilinjen mot å representere sitt valgdistrikt

Samle data

  • Skannede dokumenter fra 1910-1931
  • Tigjengelig hos Nasjonalbiblioteket
    • Last ned med “søk og klikk”

Image Title

Preprosessering – ImageMagick

convert -density 300x300 -shave 10x100;
  not_noisy.png not_noisy_clean1.png

convert not_noisy_clean1.png -normalize ;
  not_noisy_clean2.png

convert not_noisy_clean2.png ;
  -connected-components 4 -threshold 0 -negate;
  not_noisy_clean3.png

convert not_noisy_clean2.png;
  -define connected-components:area-threshold=15;
  -connected-components 4 -threshold 0 -negate; 
  not_noisy_clean4.png

convert not_noisy_clean3.png not_noisy_clean4.png;
  -compose minus -composite;
  not_noisy_clean5.png

convert not_noisy_clean2.png;
  \( -clone 0 -negate -fill white -colorize 100% \) ;
  not_noisy_clean5.png -compose Blend -composite;
  not_noisy_clean6.png

convert not_noisy_clean6.png; 
  -fill black -opaque "#FF00FF" -morphology Erode Disk:0.5; 
  not_noisy_cleaned.png

Original Clean

Preprosessering – Bilde til tekst

Clean

# https://github.com/tesseract-ocr/tesseract
tesseract not_noisy_cleaned.png tekst
head -n 10 tekst.txt
## [1] "er misbruk. Men man har reglerne; det er"   
## [2] "nødvendig for en apoteker at levere efter"  
## [3] "recept. Selvfølgelig, hvis han er viss paa,"
## [4] "at det er et misbruk, er. det hans pligt at"
## [5] "negte. Men man stiller disse samvittighets-"
## [6] "fulde apotekere i en uholdbar, vanskelig"   
## [7] "stilling ved de nuværende regler."

Preprosessering – Når ting går galt

  • Valg tatt i skanneprosessen kan ha konsekvenser
  • Grayscale vs. sort/hvit
  • Linjebrytning av ord med bindestrek

Noisy Noisy cleaned

## [1] "-Pwresldonbene: v Medi mmsyh då aperdkkktes"       
## [2] "løs inamis psangterrmeil pesosiskeh beer ajberaide"
## [3] "9 gjør 2: 3berdosn m jpas, st hen haddetenkt"      
## [4] "aa saDNg OD ,Gftennisk"                            
## [5] "sol næste vike: hadde. præsidenten"

Preprosessering – Tekst til tall (BoW)

## # A tibble: 6 × 3
##   speech_id    name_fixed                 speech                                
##   <chr>        <chr>                      <chr>                                 
## 1 speech210284 Robert Sæther              "Når den bevilgning som blir gitt und…
## 2 speech096962 Ole Andor Hoel             "Jeg forlangte ordet for at gjøre opm…
## 3 speech107950 Martinus Nikolai Sivertsen "Komiteens ordfører oplyste, at Krist…
## 4 speech113775 Anfin Øen                  "Del næste talarane hev upptil 2 minu…
## 5 speech004338 Peter Valeur               "Jeg har den opfatning, at der er gjo…
## 6 speech009899 Alfred Eriksen             "Jeg fremholdt igaar, at dersom vort …
##               features
## docs           det har jord lærere behandling park
##   speech006356   1   0    0      0          0    0
##   speech010491   3   2    9      0          0    0
##   speech012336  21  19    0      5          0    0
##   speech015337   2   0    0      0          1    0
##   speech020126  10   5    0      0          0    5
##   speech023230   8   5    0      0          1    0

Preprosessering – Hva skal med?

  • Stoppord
  • Bøyning
    • full form vs. stemming vs. lemma
    • kjærlighet vs. kjær vs. kjærlighet
  • Rekkefølge på ord
    • unigram, bigram, trigram, osv
  • Nynorsk vs. bokmål?
  • Kontekstuelle (ikke-språklige) variabler

Modellering – Emneanalyse

  • Emneanalyse (topic modelling)
    • Emner defineres av ords sameksistens
    • Satt antall emner – abstraksjonsnivå
    • Induktiv tolkning – mye lesing
  • Structural Topic Model (STM)
    • Estimere effekt av variabler på emnestruktur
    • Her med reform og stortingssesjon

Modellering – Resultat

Topic Examples

Effect

Oppsummering

  • Strukturerte data :: kaosdata
    • Out of the box
    • APIer
    • Skraping
    • Kravling
    • OCR
  • Fallgruver
    • Undersøk om back-end finnes
    • Ikke overlast serveren
    • Lagre nedlastede sidene
    • Se på robots.txt

Oppgave [1]

  1. Skissér en hypotese basert på eksisterende teorier
    • Husk iterativ prosess – ikke overtenk!
  2. Finn en datakilde du tenker kan brukes til å svare på hypotesen din
    • Pass på å ikke ta vann over hodet!
  3. Hent og strukturer data
    • Om det er mye data, start med å strukturere deler av data
  4. Gi en kort beskrivelse av hvordan dataene ble fanget og hvordan de er strukturert
    • Ta gjerne med litt om problemer som evt oppstod

Neste forelesning(er)




Forbehandling av tekst 1 (uke 36)

Forbehandling av tekst 2 (uke 37)

Bruke API (Stortinget) (uke 38)